#include "inc/os.h"

// 1s
#define TIMER_INTERVAL 50000000

/*
 * The TIMER control registers are memory-mapped at address TIMER (defined in inc/platform.h). 
 * This macro returns the address of one of the registers.
 */
#define TIMER_REG_ADDRESS(reg) ((volatile uint32_t *) (TIMER + reg))

/*
 * TIMER registers map
 * timer_count is a read-only reg
 */
#define TIMER_CTRL	0
#define TIMER_COUNT	4
#define TIMER_EVALUE	8

#define timer_read_reg(reg) (*(TIMER_REG_ADDRESS(reg)))
#define timer_write_reg(reg, data) (*(TIMER_REG_ADDRESS(reg)) = (data))

#define TIMER_EN	  1 << 0
#define TIMER_INT_EN      1 << 1
#define TIMER_INT_PENDING 1 << 2

static uint32_t _tick = 0;

void timer_load(uint32_t interval)
{
        timer_write_reg(TIMER_EVALUE, interval);
        timer_write_reg(TIMER_CTRL, (timer_read_reg(TIMER_CTRL) | (TIMER_EN)));
}

/*
 * enable timer interrupt
 */
void timer_init()
{
	timer_write_reg(TIMER_CTRL, (timer_read_reg(TIMER_CTRL) | (TIMER_INT_EN)));
	timer_load(TIMER_INTERVAL);
}

void timer_handler()
{
	timer_write_reg(TIMER_CTRL, (timer_read_reg(TIMER_CTRL) & ~(TIMER_INT_PENDING)));
	_tick++;
	printf("tick: %d\n", _tick);
	
	timer_load(TIMER_INTERVAL);

	schedule();
}
